package org.jeecg.modules.rooms.controller;


import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.Enum.ResultCode;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.util.UUIDGenerator;
import org.jeecg.modules.rooms.DTO.CesGoodsDelDto;
import org.jeecg.modules.rooms.DTO.CesGoodsDto;
import org.jeecg.modules.rooms.DTO.CesGoodsSearchDto;
import org.jeecg.modules.rooms.entity.CesGoods;
import org.jeecg.modules.rooms.entity.CesStockType;
import org.jeecg.modules.rooms.service.CesGoodsServiceImpl;
import org.jeecg.modules.rooms.service.CesStockTypeServiceImpl;
import org.jeecg.modules.rooms.util.Pinyin4jUtil;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 商品表 前端控制器
 * </p>
 *
 * @author fendo
 * @since 2023-03-13
 */
@RestController
@RequestMapping("/rooms/cesGoods")
@Api(tags="CesGoodsController")
@Slf4j
public class CesGoodsController extends JeecgController<CesGoods,CesGoodsServiceImpl> {

    @Resource
    private CesGoodsServiceImpl goodsService;
    @Resource
    private CesStockTypeServiceImpl cesStockTypeService;

    /***
     * 查询
     * @param dto
     * @return
     */
    @ApiOperation(value = "查询", notes = "查询")
    @GetMapping(value = "/list")
    public Result list(CesGoodsSearchDto dto) {
        if (StringUtils.isBlank(dto.getHotelId())) {
            return Result.error(ResultCode.PARAM_MISS);
        }
        if (dto.getPageNo().intValue() <= 0) {
            return Result.error("页数不能小于等于0");
        }
        if (dto.getPageSize().intValue() < 10) {
            return Result.error("分页条数不能小于10");
        }
        try {
            return goodsService.fetchList(dto);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }

    /***
     * 查询
     * @param dto
     * @return
     */
    @ApiOperation(value = "查询", notes = "查询")
    @GetMapping(value = "/queryList")
    public Result queryList(CesGoodsSearchDto dto) {
        if (StringUtils.isBlank(dto.getHotelId())) {
            return Result.error(ResultCode.PARAM_MISS);
        }
        try {
            return goodsService.queryList(dto);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }


    @ApiOperation(value = "创建", notes = "创建")
    @PostMapping(value = "/create")
    public Result create(@RequestBody CesGoodsDto dto) {
        if (StringUtils.isBlank(dto.getHotelId())) {
            return Result.error(ResultCode.PARAM_MISS);
        }
        if (StringUtils.isBlank(dto.getGoodType())) {
            return Result.error(ResultCode.PARAM_MISS);
        }
        if (StringUtils.isBlank(dto.getGoodUnit())) {
            return Result.error(ResultCode.PARAM_MISS);
        }
        if (StringUtils.isBlank(dto.getBarCode())) {
            return Result.error(ResultCode.PARAM_MISS);
        }
        if (StringUtils.isBlank(dto.getName())) {
            return Result.error(ResultCode.PARAM_MISS);
        }
        if (StringUtils.isBlank(dto.getBid().toString())) {
            return Result.error(ResultCode.PARAM_MISS);
        }
        if (StringUtils.isBlank(dto.getSellingPrice().toString())) {
            return Result.error(ResultCode.PARAM_MISS);
        }
        if (dto.getPurchases().intValue() < 0) {
            return Result.error(ResultCode.PARAM_MISS);
        }
        if (dto.getSalesVolume().intValue() < 0) {
            return Result.error(ResultCode.PARAM_MISS);
        }
        if (dto.getInventory().intValue() < 0) {
            return Result.error(ResultCode.PARAM_MISS);
        }
        try {
            dto.setSimplySpell(Pinyin4jUtil.toPinYinUppercase(dto.getName()));
            return goodsService.create(dto);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }


    @ApiOperation(value = "修改", notes = "修改")
    @PutMapping(value = "/modify")
    public Result modify(@RequestBody CesGoodsDto dto) {
        if (StringUtils.isBlank(dto.getHotelId())) {
            return Result.error(ResultCode.PARAM_MISS);
        }
        if (StringUtils.isBlank(dto.getId())) {
            return Result.error(ResultCode.PARAM_MISS);
        }
        dto.setSimplySpell(Pinyin4jUtil.toPinYinUppercase(dto.getName()));
        try {
            return goodsService.modify(dto);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }

    @ApiOperation(value = "删除", notes = "删除")
    @DeleteMapping(value = "/delete")
    public Result delete(String id, String hotelId) {
        if (StringUtils.isBlank(hotelId)) {
            return Result.error(ResultCode.PARAM_MISS);
        }
        if (StringUtils.isBlank(id)) {
            return Result.error(ResultCode.PARAM_MISS);
        }
        try {
            return goodsService.delete(id, hotelId);
        } catch (Exception e) {

            return Result.error(e.getMessage());
        }
    }

    @ApiOperation(value = "删除", notes = "删除")
    @DeleteMapping(value = "/delBatch")
    public Result delBatch(@RequestBody CesGoodsDelDto dto) {
        if (StringUtils.isBlank(dto.getIdStr())) {
            return Result.error(ResultCode.PARAM_MISS);
        }
        try {
            List<String> ids = Stream.of(dto.getIdStr().split(",")).collect(Collectors.toList());
            return goodsService.delBatch(ids);
        } catch (Exception e) {
            return Result.error(e.getMessage());
        }
    }

    /**
     * 添加临时菜品
     *
     * @param cesGoods
     * @return
     */
    @AutoLog(value = "添加临时菜品")
    @ApiOperation(value = "添加临时菜品", notes = "添加临时菜品")
    @PostMapping(value = "/addTemp")
    public Result<CesGoods> addTemp(@RequestBody CesGoods cesGoods) {
        //临时
        cesGoods.setIsTemp(true);
        cesGoods.setInvalid(false);
        cesGoods.setBarCode("");
        cesGoods.setBid(BigDecimal.ZERO);
        cesGoods.setPurchases(99999);
        cesGoods.setInventory(99999);
        cesGoods.setSalesVolume(0);
        cesGoods.setCreatAt(LocalDateTime.now());
        cesGoods.setUpdateAt(LocalDateTime.now());
        cesGoods.setId(UUIDGenerator.generate());
        goodsService.save(cesGoods);
        return Result.OK(cesGoods);
    }

    /**
     * 适用于客房商品
     *
     * @param cesGoods
     * @param pageNo
     * @param pageSize
     * @param req
     * @return
     */
    @ApiOperation(value = "适用于客房商品", notes = "适用于客房商品")
    @GetMapping(value = "/kf-goods-list")
    public Result<IPage<CesGoods>> queryKfGoodsPageList(CesGoods cesGoods,
                                                        @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                        @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
                                                        HttpServletRequest req) {
        LambdaQueryWrapper<CesGoods> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CesGoods::getInvalid, false);
        queryWrapper.eq(CesGoods::getIsTemp, false);
        if (StrUtil.isNotEmpty(cesGoods.getName())) {
            queryWrapper.and(e -> e.eq(CesGoods::getBarCode, cesGoods.getName()).or().
                    like(CesGoods::getName, cesGoods.getName()).or().like(CesGoods::getSimplySpell, cesGoods.getName().toUpperCase()));
        }
        if (StrUtil.isNotEmpty(cesGoods.getGoodType())){
            List<CesStockType> list = cesStockTypeService.list(Wrappers.<CesStockType>lambdaQuery().eq(CesStockType::getParentId, cesGoods.getGoodType()));
            queryWrapper.and(e -> {
                e = e.or().eq(CesGoods::getGoodType, cesGoods.getGoodType());
                for (CesStockType ele : list) {
                    e = e.or().eq(CesGoods::getGoodType, ele.getId());
                }
            });
        }

        LambdaQueryWrapper<CesStockType> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(CesStockType::getHotelId, cesGoods.getHotelId());
        lambdaQueryWrapper.eq(CesStockType::getState, true);
        lambdaQueryWrapper.eq(CesStockType::getParentId, "0");
        lambdaQueryWrapper.eq(CesStockType::getInvalid, false);
        lambdaQueryWrapper.like(CesStockType::getApplyScope, "1");
        List<CesStockType> goodTypes = cesStockTypeService.list(lambdaQueryWrapper);
        if (ObjectUtils.isNotEmpty(goodTypes)) {
            List<CesStockType> list = cesStockTypeService.list(Wrappers.<CesStockType>lambdaQuery()
                    .eq(CesStockType::getHotelId, cesGoods.getHotelId())
                    .eq(CesStockType::getInvalid, false));
            queryWrapper.and(j -> {
                for (int k = 0; k < goodTypes.size(); k++) {
                    String id = goodTypes.get(k).getId();
                    List<CesStockType> stockTypeList = list.stream().filter(t -> t.getParentId().equals(id)).collect(Collectors.toList());
                    if (ObjectUtils.isNotEmpty(stockTypeList)) {
                        for (int z = 0; z < stockTypeList.size(); z++) {
                            j = j.or().eq(CesGoods::getGoodType, stockTypeList.get(z).getId());
                        }
                    }
                    j = j.or().eq(CesGoods::getGoodType, id);
                }
            });
            Page<CesGoods> page = new Page<CesGoods>(pageNo, pageSize);
            IPage<CesGoods> pageList = goodsService.page(page, queryWrapper);
            return Result.OK(pageList);
        } else {
            IPage<CesGoods> pageList = new Page<>();
            return Result.OK(pageList);
        }
    }
}

